home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Development Kits / HyperCard Related / APDA HyperCard Toolkits / CD Audio Toolkit 1.0 / Source / Track.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-07  |  7.0 KB  |  283 lines  |  [TEXT/MPS ]

  1. /*
  2.     CDRemainingTrack - An XFCN to report remaining time on disc
  3.     ©Apple Computer, Inc. 1988
  4.     All Rights Reserved.
  5.     
  6.     88/11/08    BL°B    First Version
  7.  
  8.     To compile and link this file using Macintosh Programmer's Workshop,
  9.  
  10.     C -q2 CDRemainingTrack.c
  11.     link -sn Main=CDRemainingTrack -sn STDIO=CDRemainingTrack ∂
  12.          -sn INTENV=CDRemainingTrack -rt XFCN=42 ∂
  13.          -m CDRemainingTrack CDRemainingTrack.c.o "{CLibraries}"CRuntime.o ∂
  14.          "{CLibraries}"StdCLib.o ∂
  15.          -o HyperCommands
  16.          
  17.     This link directive puts the XCMD in the file "HyperCommands".
  18.     Substitute the name of the stack you want it in.  To move XCMDs
  19.     between stacks, use ResEdit.  They can be in an individual stack,
  20.     the Home stack, the HyperCard application, or the System File.
  21.     
  22. */
  23.  
  24. #include <cd.h>
  25.  
  26. #define BUGSTART    79    /* last good track for TrackStart */
  27.  
  28. /* local procedure definitions */
  29. OSErr DriverBugHack(short, long, long *, long *, long *);
  30.  
  31. /************************************************************************
  32.  *
  33.  *  Function:        ReadQ
  34.  *
  35.  *  Purpose:        return track & time for current position
  36.  *
  37.  *  Returns:        OSErr.  Probably either
  38.  *                        noErr        everything's hunky-dory!
  39.  *                        paramErr    you messed up the call somehow.
  40.  *
  41.  *  Side Effects:    none
  42.  *
  43.  *  Description:    Simply call the driver with a READQ call.  The track
  44.  *                    number and absolute minute, second, block come back
  45.  *                    in BCD.  Convert them to decimal and return.
  46.  *
  47.  ************************************************************************/
  48. OSErr
  49. ReadQ(refNum, trackNo, minute, second, block)
  50. short    refNum;
  51. long    *trackNo;
  52. long    *minute;
  53. long    *second;
  54. long    *block;
  55. {
  56.     CDParam    myPB;
  57.     OSErr    result;
  58.     
  59.     myPB.ioCompletion = 0;
  60.     myPB.ioNamePtr = (char *) 0;
  61.     myPB.ioVRefNum = 1;
  62.     myPB.ioCRefNum = refNum;
  63.     myPB.csCode = READQ;
  64.     
  65.     result = PBControl(&myPB, false);
  66.     
  67.     if (result == noErr)
  68.     {
  69.         *trackNo = (long) BCD2DECIMAL(myPB.csParam[1]);
  70.         *minute = (long) BCD2DECIMAL(myPB.csParam[6]);
  71.         *second = (long) BCD2DECIMAL(myPB.csParam[7]);
  72.         *block = (long) BCD2DECIMAL(myPB.csParam[8]);
  73.     }
  74.     return result;
  75. }
  76.  
  77.  
  78. /************************************************************************
  79.  *
  80.  *  Function:        DiscTime
  81.  *
  82.  *  Purpose:        return total time on this disc
  83.  *
  84.  *  Returns:        OSErr
  85.  *                    either noErr if everything was okay
  86.  *                    or some parameter error from driver call.
  87.  *
  88.  *  Side Effects:
  89.  *                    fills in totalMinute, totalSecond, totalBlock
  90.  *
  91.  *  Description:
  92.  *                    call the driver ReadTOC call to get the appropriate
  93.  *                    information.  Ask for the "lead-out" time, which is
  94.  *                    the end of the disc.
  95.  *
  96.  ************************************************************************/
  97. OSErr
  98. DiscTime(refNum, minute, second, block)
  99. short    refNum;
  100. long    *minute;
  101. long    *second;
  102. long    *block;
  103. {
  104.     CDParam    myPB;
  105.     OSErr    result;
  106.     
  107.     myPB.ioCompletion = 0;
  108.     myPB.ioNamePtr = (char *) 0;
  109.     myPB.ioVRefNum = 1;
  110.     myPB.ioCRefNum = refNum;
  111.     myPB.csCode = READTOC;
  112.     myPB.csParam[0] = 0;
  113.     myPB.csParam[1] = 2;     /* request lead-out time */
  114.     
  115.     result = PBControl(&myPB, false);
  116.     
  117.     if (result == noErr)
  118.     {
  119.         *minute = (long) BCD2DECIMAL(myPB.csParam[0]);
  120.         *second = (long) BCD2DECIMAL(myPB.csParam[1]);
  121.         *block = (long) BCD2DECIMAL(myPB.csParam[2]);
  122.     }
  123.     return result;
  124. }
  125.  
  126.  
  127.  
  128.  
  129. /************************************************************************
  130.  *
  131.  *  Function:        TimeDiff
  132.  *
  133.  *  Purpose:        calculate difference between two times
  134.  *
  135.  *  Returns:        nothing
  136.  *
  137.  *  Side Effects:    fills rMinute, rSecond, rBlock
  138.  *
  139.  *  Description:    convert the absolute times designated by
  140.  *                    {m1, s1, b1} and {m2, s2, b2} to absolute
  141.  *                    blocks.  Subtract the second time from the
  142.  *                    first.  Convert the result back to {m, s, f}
  143.  *                    format.
  144.  *
  145.  ************************************************************************/
  146. void
  147. TimeDiff(rMinute, rSecond, rBlock, m1, s1, b1, m2, s2, b2)
  148. long    *rMinute;
  149. long    *rSecond;
  150. long    *rBlock;
  151. long    m1, s1, b1, m2, s2, b2;
  152. {
  153.     long    time1, time2;
  154.     long    minute, second, block;
  155.     
  156.     time1 = b1 + (s1 * BLOCKSEC) + (m1 * BLOCKMIN);
  157.     time2 = b2 + (s2 * BLOCKSEC) + (m2 * BLOCKMIN);
  158.     
  159.     time1 = time1 - time2;
  160.     
  161.     minute = time1 / BLOCKMIN;
  162.     time1 = time1 - (minute * BLOCKMIN);
  163.     
  164.     second = time1 / BLOCKSEC;
  165.     block = time1 - (second * BLOCKSEC);
  166.     
  167.     *rMinute = minute;
  168.     *rSecond = second;
  169.     *rBlock = block;
  170. }
  171.  
  172. /************************************************************************
  173.  *
  174.  *  Function:        TrackStart
  175.  *
  176.  *  Purpose:        return start of specified track
  177.  *
  178.  *  Returns:        OSErr.  Probably either
  179.  *                        noErr        everything's hunky-dory!
  180.  *                        paramErr    you messed up the call somehow.
  181.  *
  182.  *  Side Effects:    modifies "minute", "second", and "block" to indicate
  183.  *                    start of current track.
  184.  *
  185.  *  Description:    Simply call the driver and return the values
  186.  *                    byte that the driver gives us.  See the developer's
  187.  *                    guide for information about the READTOC command.
  188.  *
  189.  ************************************************************************/
  190. OSErr
  191. TrackStart(refNum, trackNo, minute, second, block)
  192. short    refNum;
  193. long    trackNo;
  194. long    *minute;
  195. long    *second;
  196. long    *block;
  197. {
  198.     CDPlay3Param    myPB;
  199.     OSErr    result;
  200.     char    track[4];
  201.     
  202.     if (trackNo > BUGSTART)
  203.         result = DriverBugHack(refNum, trackNo, minute, second, block);
  204.     else
  205.     {
  206.         myPB.ioCompletion = 0;
  207.         myPB.ioNamePtr = (char *) 0;
  208.         myPB.ioVRefNum = 1;
  209.         myPB.ioCRefNum = refNum;
  210.         myPB.csCode = READTOC;
  211.         myPB.readType = 3;
  212.         myPB.bufAddr = track;
  213.         myPB.bufferLength = 4;
  214.         myPB.track = DECIMAL2BCD(trackNo);
  215.         
  216.         result = PBControl(&myPB, false);
  217.         *minute = (long) BCD2DECIMAL(track[1]);
  218.         *second = (long) BCD2DECIMAL(track[2]);
  219.         *block = (long) BCD2DECIMAL(track[3]);
  220.     }
  221.     return result;
  222. }
  223.  
  224. /************************************************************************
  225.  *
  226.  *  Function:        DriverBugHack
  227.  *
  228.  *  Purpose:        read TOC to get around driver bug
  229.  *
  230.  *  Returns:        OSErr
  231.  *                    usually 0, but can be negative if driver returns
  232.  *                    an error
  233.  *
  234.  *  Side Effects:    fills minute, second, and block with the correct
  235.  *                    values for the specified track.
  236.  *
  237.  *  Description:    There is a bug in the Apple CD-ROM driver 2.0
  238.  *                    which makes it return incorrect information for
  239.  *                    a track greater than 79 if you ask for it alone.
  240.  *                    We ask for tracks 79 through the specified track.
  241.  *                    This should get around the bug.
  242.  *
  243.  ************************************************************************/
  244. OSErr
  245. DriverBugHack(refNum, trackNo, minute, second, block)
  246. short        refNum;
  247. long        trackNo;
  248. long        *minute;
  249. long        *second;
  250. long        *block;
  251. {
  252.     CDPlay3Param    myPB;
  253.     OSErr    result;
  254.     char    *track;
  255.     short    trackSize;
  256.     short    i;
  257.     
  258.     trackSize = (short)trackNo * 4;    /* 4 bytes per track in call */
  259.     track = NewPtr(trackSize);
  260.     if (track == nil)
  261.         result = MemError();
  262.     else
  263.     {
  264.         myPB.ioCompletion = 0;
  265.         myPB.ioNamePtr = (char *) 0;
  266.         myPB.ioVRefNum = 1;
  267.         myPB.ioCRefNum = refNum;
  268.         myPB.csCode = READTOC;
  269.         myPB.readType = BUFADDR;
  270.         myPB.bufAddr = track;
  271.         myPB.bufferLength = trackSize;
  272.         myPB.track = 0x01;        /* BCD */
  273.         
  274.         result = PBControl(&myPB, false);
  275.         i = (trackNo - 1) * 4;
  276.         *minute = (long) BCD2DECIMAL(track[i+1]);
  277.         *second = (long) BCD2DECIMAL(track[i+2]);
  278.         *block = (long) BCD2DECIMAL(track[i+3]);
  279.         DisposPtr(track);
  280.     }
  281.     return result;
  282. }
  283.